<template>
  <div>
    <navback title="注册" @back="goback()"></navback>
    <van-form @submit="onSubmit" ref="RegisterForm">
      <van-field
        v-model="username"
        required
        name="username"
        label="用户名"
        placeholder="用户名"
        :rules="[
          { required: true, message: '请填写用户名' },
          {
            validator: patternusername,
            message: '用户名必须以字母+数字组成，且不能以数字开头',
          },
          { validator: usernamevalidator, message: '用户名重复' },
        ]"
      />
      <van-field
        v-model="password"
        required
        type="password"
        name="password"
        label="密码"
        placeholder="密码"
        :rules="[
          { required: true, message: '请填写密码' },
          { validator: passwordvalidator, message: '格式为:字母+数字 6-18位' },
        ]"
      />
      <van-field
        v-model="password2"
        required
        type="password"
        name="password2"
        label="确认密码"
        placeholder="再次确认密码"
        :rules="[
          { required: true, message: '请确认密码' },
          { validator: repasswordvalidator, message: '两次输入密码不一致' },
        ]"
      />
      <van-field
        v-model="phone"
        name="phone"
        required
        label="手机号"
        placeholder="请输入手机号"
        :rules="[
          { required: true, message: '请输入手机号' },
          { validator: phonevalidator, message: '手机号格式不正确' },
        ]"
      />
      <van-field
        v-model="sms"
        required
        name="sms"
        center
        clearable
        label="短信验证码"
        placeholder="请输入短信验证码"
        :rules="[{ required: true, message: '请输入短信验证码' }]"
      >
        <template #button>
          <van-button
            native-type="button"
            size="small"
            color="#07c160"
            :disabled="SMSCd"
            @click="toSMS()"
            >{{ SMSCdTimer }}</van-button
          >
        </template>
      </van-field>

      <van-field name="sex" label="性别">
        <template #input>
          <van-radio-group v-model="sex" direction="horizontal">
            <van-radio name="1">男</van-radio>
            <van-radio name="2">女</van-radio>
            <van-radio name="">保密</van-radio>
          </van-radio-group>
        </template>
      </van-field>
      <van-field name="fileList" label="头像">
        <template #input>
          <van-uploader
            v-model="fileList"
            accept="image/*"
            image-fit="cover"
            max-count="1"
            :before-read="beforeRead"
            :after-read="afterRead"
          />
        </template>
      </van-field>
      <van-field
        readonly
        clickable
        name="areatext"
        :value="areatext"
        label="地址"
        placeholder="点击选择省市区"
        @click="showArea = true"
      />
      <van-popup v-model="showArea" position="bottom">
        <van-area
          :area-list="areaList"
          @confirm="onConfirmArea"
          @cancel="showArea = false"
          name="area"
          :value="area"
        />
      </van-popup>
      <div style="margin: 16px">
        <van-button round block type="info" native-type="submit"
          >提交</van-button
        >
      </div>
    </van-form>
  </div>
</template>

<script>
import {
  checkUsername,
  sendSMS,
  calcSMS,
  register,
  phoneused,
} from "@/api/user";
import { Dialog, Toast } from "vant";
import { areaList } from "@vant/area-data";
import JSEncrypt from "jsencrypt";
import { mapGetters } from "vuex";
import navback from "@/components/navback/navback";
import singleupload from "@/api/singleupload";
export default {
  name: "register",
  data() {
    return {
      username: "",
      password: "",
      password2: "",
      phone: "",
      sms: "", //短信验证码
      sex: "",
      tx:"",
      fileList: [], //上传的文件
      area: "", //地址  110121
      areadetail: "", //地址[{code:,name:},{},{}]
      areatext: "",
      showArea: false, //地址弹窗展示
      areaList: areaList, //地址数据
      SMSCd: false, //发送验证码按钮cd
      SMSCdTimer: "发送验证码",
      RequestId: "", //接口id
    };
  },
  created() {
    //this.$store.dispatch('app/pubKey'); //获取公钥
  },
  computed: {
    ...mapGetters(["PubKey"]),
  },
  methods: {
    goback() {
      this.$router.go(-1);
    },
    onSubmit(values) {
      if (!this.sms) {
        Toast.fail("请输入短信验证码");
        return;
      }

      if (!this.RequestId) {
        Toast.fail("短信发送失败，请稍后再试");
        return;
      }
      if (!this.PubKey) {
        Toast.fail("服务器错误,请稍后再试");
      }
      let FormData = values;

      //头像
      if (FormData.fileList.length > 0 && this.tx) {
        delete FormData.fileList;
        FormData["tx"] = this.tx;
      } else {
        FormData["tx"] = "";
      }
      if (this.area) {
        FormData["area"] = this.area;
      }
      FormData["RequestId"] = this.RequestId;

      try {
        delete FormData.password2;
        let password = FormData["password"];
        let encryptor = new JSEncrypt(); // 新建JSEncrypt对象
        encryptor.setPublicKey(this.PubKey); // 设置公钥
        password = encryptor.encrypt(password); // 对需要加密的数据进行加密
        FormData["password"] = password;
      } catch (err) {
        Dialog.alert({
          title: "错误",
          message: "程序错误",
        }).then(() => {
          return;
          //this.$refs['RegisterForm'].resetFields();
        });
      }
      console.log("FormData", FormData);
      //链式调用api
      calcSMS(FormData["RequestId"], FormData["sms"])
        .then((data) => {
          console.log("data", data);
          //验证码正确，注册
          return register(FormData);
        })
        .then((res) => {
          console.log("res", res);
          console.log("----链式调用api----");
          Toast.success(res.message);
          this.$router.push("/user/login");
        })
        .catch((err) => {
          console.log("err", err);
          Toast.fail(err);
        });
    },
    onConfirmArea(values) {
      this.areadetail = values;
      this.area = values[2].code;

      this.areatext = values
        .filter((item) => !!item)
        .map((item) => item.name)
        .join("/");
      this.showArea = false;
    },
    async toSMS() {
      if (this.SMSCd) {
        //冷却中
        return;
      }

      //手机号码格式
      if (/^[1-9]{1}[0-9]{10}$/.test(this.phone)) {
        //手机号是否已被占用
        let cdtimer = null;
        phoneused(this.phone)
          .then((data) => {
            this.SMSCd = true;
            this.SMSCdTimer = 60;
            cdtimer = setInterval(() => {
              this.SMSCdTimer -= 1;
              if (this.SMSCdTimer < 1) {
                clearInterval(cdtimer);
                this.SMSCd = false;
                this.SMSCdTimer = "发送验证码";
              }
            }, 1000);

            return sendSMS(this.phone); //发送短信
          })
          .then((res) => {
            //调用接口发送验证码
            this.RequestId = res.data.RequestId;
          })
          .catch((err) => {
            Dialog.alert({
              message: err,
            }).then(() => {
              if (!cdtimer) {
                clearInterval(cdtimer);
                this.SMSCd = false;
                this.SMSCdTimer = "发送验证码";
              }
            });
          });
      } else {
        Toast.fail("请先填写正确的手机号");
      }
    },
    patternusername(val) {
      return /^(?![0-9]+.+$)(?![a-zA-Z]+$)(?![0-9]+$)[a-zA-Z0-9]+$/.test(val);
    },
    phonevalidator(val) {
      return /^[1-9]{1}[0-9]{10}$/.test(val);
    },
    usernamevalidator(val) {
      return new Promise((resolve) => {
        Toast.loading("验证中...");
        checkUsername(val)
          .then((data) => {
            if (data.data == 0) {
              Toast.clear();
              resolve(true);
            } else {
              Toast.clear();
              resolve(false);
            }
          })
          .catch((err) => {
            Toast.clear();
            resolve(false);
          });
      });
    },
    passwordvalidator(val) {
      //字母+数字  6-18位
      return /^(?![a-zA-Z]+$)(?![0-9]+$)[a-zA-Z0-9]{6,18}$/.test(val);
    },
    repasswordvalidator(val) {
      if (this.password != this.password2) {
        return false;
      }
    },
    beforeRead(file) {
      //上传之前校验
      if (!/^image\/.*$/.test(file.type)) {
        Toast("只允许上传图片！");
        return false;
      }
      return true;
    },
    async afterRead(file) {
      file.status = 'uploading';
      file.message = '上传中...';
      
      //上传文件
      await singleupload(file.file)
        .then((data) => {
          file.status = 'done';
          file.message = '上传成功';
          this.tx = data.data.path;
        })
        .catch((err) => {
          file.status = 'failed';
          file.message = '上传失败';
          Toast.fail("系统异常");
          return;
        });
    },
  },
  components: {
    navback,
  },
};
</script>

<style lang="scss" scoped>
.SMScd {
}
</style>